package com.pachong.android.frameworkbase.utils;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * bitmap 工具类
 *
 * @Author: PV
 * @E-mail: pengveivei@sina.cn
 * @CreateDate: 2016-06-20
 * @Version: 1.0.0
 */
public class BitmapUtil {

	public BitmapUtil() {
	}


	/**
	 * 通过图片路径调用BitmapFactory.decodeFile() 压缩图片
	 * 
	 * @param picPath
	 *            图片文件路径
	 * @param reqWidth
	 *            期望的图片宽度
	 * @param reqHeight
	 *            期望的图片高度
	 * @return
	 */
	public static Bitmap decodeBitmapFromFilePath(String picPath, int reqWidth, int reqHeight) {
		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(picPath, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(picPath, options);
	}


	/**
	 * 通过BitmapFactory.decodeStream()压缩图片 容易出现错误：SkImageDecoder::Factory
	 * returned null， 不建议用这个
	 * 
	 * @param is
	 * @param rect
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static Bitmap decodeBitmapFromStream(InputStream is, Rect rect, int reqWidth, int reqHeight) {

		// First decode with inJustDecodeBounds=true to check dimensions
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeStream(is, rect, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeStream(is, rect, options);
	}


	/**
	 * 计算inSampleSize值，不同的值代表不同的压缩比例
	 * 
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			// Calculate the largest inSampleSize value that is a power of 2 and
			// keeps both
			// height and width larger than the requested height and width.
			while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
				inSampleSize *= 2;
			}
		}

		return inSampleSize;
	}


	/**
	 * 将bitmap转为drawable
	 * 注意，BitmapDrawable已经过期了，SDK > 1.5的情况下会自动根据当前的density等比例处理图片
	 * 
	 * @param bitmap
	 * @param density
	 *            密度 跟设备相关
	 * @return
	 */
	public static Drawable bitmap2Drawable(Bitmap bitmap, float density) {
		if (density > 0) {
			bitmap.setDensity((int) density);
		}
		BitmapDrawable bd = new BitmapDrawable(bitmap);
		return bd;
	}


	/**
	 * Drawable 转 bitmap
	 * 
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawable2Bitmap(Drawable drawable) {
		if (drawable instanceof BitmapDrawable) {
			return ((BitmapDrawable) drawable).getBitmap();
		} else if (drawable instanceof NinePatchDrawable) {
			Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
					drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
							: Bitmap.Config.RGB_565);
			Canvas canvas = new Canvas(bitmap);
			drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
			drawable.draw(canvas);
			return bitmap;
		} else {
			return null;
		}
	}


	/**
	 * 获取drawableId指定的对象的bitmap
	 * 
	 * @param context
	 * @param drawableId
	 * @return
	 */
	public static Bitmap getBitmapWith(Context context, int drawableId) {
		Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), drawableId);
		return bmp;
	}


	/**
	 * bitmap 转 bytes
	 * 
	 * @param bm
	 * @return
	 */
	public static byte[] bitmap2Bytes(Bitmap bm) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
		return baos.toByteArray();
	}


	/**
	 * byte 转 bitmap
	 * 
	 * @param b
	 * @return
	 */
	public static Bitmap bytes2Bitmap(byte[] b) {
		if (b != null && b.length > 0) {
			return BitmapFactory.decodeByteArray(b, 0, b.length);
		} else {
			return null;
		}

	}


	public static Bitmap resizeBitmap(Context context, Bitmap srcBmp, int width, int height, boolean isDip) {
		int newWidth = width;
		int newHeight = height;
		if (isDip) {
			newWidth = DimensionUtil.dip2px(context, width);
			newHeight = DimensionUtil.dip2px(context, height);
		}

		return resize(srcBmp, newWidth, newHeight);
	}


	public static Bitmap resize(Bitmap bmp1, int newWidth, int newHeight) {
		if (bmp1 == null) {
			return null;
		}
		int width = bmp1.getWidth();
		int height = bmp1.getHeight();
		// 计算缩放率，新尺寸除原始尺寸
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		// 创建操作图片用的matrix对象
		Matrix matrix = new Matrix();

		// 缩放图片动作
		matrix.postScale(scaleWidth, scaleHeight);

		// 创建新的图片
		Bitmap resizedBitmap = Bitmap.createBitmap(bmp1, 0, 0, width, height, matrix, true);
		return resizedBitmap;
	}


	/**
	 * 将bitmap保存为文件
	 * 
	 * @param bitmap
	 * @param absFilename
	 *            这里不判断路径是否存在，默认他是存在的
	 * @param removeIfExist
	 * @return
	 */
	public static boolean saveBitmap(Bitmap bitmap, String absFilename, boolean removeIfExist) {
		if (bitmap == null) {
			return false;
		}
		boolean ret = false;
		String tmpName = absFilename + "_tmp";
		File tmpFile = new File(tmpName);

		try {
			tmpFile.createNewFile();
			FileOutputStream fOut = null;
			try {
				fOut = new FileOutputStream(tmpFile);
				bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
				ret = true;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				ret = false;
			} finally {
				try {
					fOut.flush();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					fOut.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		if (ret == true) {
			File f = new File(absFilename);
			if (f.exists() && removeIfExist) {
				f.delete();
			}
			tmpFile.renameTo(f);
		}

		return ret;
	}


	/**
	 * 将路径中的image转成bitmap到内存
	 * @param absFilename
	 * @return
     */
	public static Bitmap decodeFile(String absFilename) {
		Bitmap bmp = BitmapFactory.decodeFile(absFilename);
		return bmp;
	}

}
